package com.xiong.ai.service;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.xiong.ai.exception.BusinessException;
import com.xiong.ai.strategy.FileStrategyProcessor;
import com.xiong.ai.vo.MessageVo;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;

/**
 * @program: ai
 * @description:
 * @author: Mr.熊
 * @create: 2024-05-31 09:06
 **/
@Service
public class AiService {

    private static final Logger LOGGER = LoggerFactory.getLogger(AiService.class);

    @Value("${ai.accessTokenUrl}")
    private String accessTokenUrl;

    @Value("${ai.apiKey}")
    private String apiKey;

    @Value("${ai.secretKey}")
    private String secretKey;

    @Value("${ai.requestUrl}")
    private String requestUrl;

    @Value("${ai.callWord}")
    private String callWord;

    @Resource
    private FileStrategyProcessor fileStrategyProcessor;

    static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().connectTimeout(2, TimeUnit.MINUTES).readTimeout(2, TimeUnit.MINUTES).build();

    public String getFileContent(MultipartFile file) {
        //获取文件后缀
        String fileType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")).toLowerCase();
        //选择对应文件的策略处理
        LOGGER.info("进行文件内容解析");
        String content = fileStrategyProcessor.selectFileStrategy(fileType).doAnalyze(file);
        //请求ai进行总结
        LOGGER.info("文件内容解析完成");
        return request(content);
    }

    /**
     * 请求ai
     *
     * @param content 文件内容
     * @return 总结
     */
    public String request(String content) {
        MediaType mediaType = MediaType.parse("application/json");
        MessageVo messageVo = new MessageVo();
        MessageVo.Message message = new MessageVo.Message();
        message.setContent(String.format(callWord, content));
        messageVo.setMessages(Arrays.asList(message));
        RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(messageVo));
        String accessToken = null;
        LOGGER.info("开始获取accessToken");
        try {
            accessToken = getAccessToken();
        } catch (Exception e) {
            LOGGER.error("获取accessToken失败，原因为：{}", e.getMessage());
            throw new BusinessException("请求失败");
        }
        LOGGER.info("获取accessToken成功，数据为：{}", accessToken);
        Request request = new Request.Builder().url(requestUrl + accessToken).method("POST", body).addHeader("Content-Type", "application/json").build();
        Response response = null;
        String resContent = null;
        LOGGER.info("请求ai总结");
        try {
            response = HTTP_CLIENT.newCall(request).execute();
            resContent = response.body().string();
        } catch (Exception e) {
            LOGGER.error("请求ai失败，原因为：{}", e.getMessage());
            throw new BusinessException("请求失败");
        }
        LOGGER.info("ai总结完成");
        return JSONObject.parseObject(resContent).get("result").toString();
    }

    /**
     * 从用户的AK，SK生成鉴权签名（Access Token）
     *
     * @return 鉴权签名（Access Token）
     */
    private String getAccessToken() throws IOException {
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "grant_type=client_credentials&client_id=" + apiKey + "&client_secret=" + secretKey);
        Request request = new Request.Builder().url(accessTokenUrl).method("POST", body).addHeader("Content-Type", "application/x-www-form-urlencoded").build();
        Response response = HTTP_CLIENT.newCall(request).execute();
        JSONObject jsonObject = JSONObject.parseObject(response.body().string());
        return jsonObject.get("access_token").toString();
    }
}
